<script setup>
    import { ref, computed, watch, onUnmounted } from "vue";
    import request from "@/common/utils/request"
    import { ArrowLeftOutlined, ArrowRightOutlined, Loading3QuartersOutlined } from '@ant-design/icons-vue'
    import { useElementBounding, useElementVisibility,useDebounceFn } from '@vueuse/core'
    import { message } from 'ant-design-vue'
    import store from "@/store/index";
    import { isDef, isUnDef, isEmpty } from "@/common/utils/is"
    import utils from "@/common/utils/utils";

    const props = defineProps({
        appKey: {
            type: String,
            default: ''
        },
        accountId:{//账号的账号id
            type:[Number,String],
            default:'',
        },
        area: { //账号需要绑定的地区
            type: Object,
            default:()=>{}
      },

      // 代理地址
      proxy: {
        type: String,
        default: ''
      },
      // 用户代理
      userAgent:{
        type: String,
        default: ''
      }
    })

    const emit = defineEmits(['logined','onError'])
    // 设置抖音主机构授权页面loading
    let pageLoading = ref(false)
    const appList = ref([])
    const windowViewRef = ref()
    const { x, y, width, height } = useElementBounding(windowViewRef)
    const targetIsVisible = useElementVisibility(windowViewRef)
    const browerView = ref()
    const authorizeTimer = ref()

    const getAppList = async () => {
      let { result } = await request.get("/work_ai", "/org/platform/account/shotStackList", { filterShow: 1 })
      return result
    }

    appList.value = await getAppList()

    const app = computed(() => {
        return appList.value.find(item => item.key === props.appKey)
    })

    watch(() => props.appKey, (val) => {
        if(! val){
            destoryAppWindow()
        }
    })

    watch(targetIsVisible, (visible) => {
        if(visible){
            createAppWindow()
        }else{
            destoryAppWindow()
        }
    })
    // 返回扫码授权页面地址
    const scanQRCode = async () => {
        if( !props.appKey){
            return
        }
        let params = {source:props.appKey, team_id: store.state.user.teamId,}
        if(props.accountId){
            params.id = props.accountId
        }
        params.area = props.area
        try{
            let result = await request.post("/work_ai", "/org/platform/account/user/authorize", params)
            return result
        }catch(err){
            if(err.code==37100){
                message.error(err.msg)
            }
        }

    }

    // 查询用户授权是否成功
    const checkUserAuthorize = async (key) => {
        authorizeTimer.value = setTimeout(async () => {
            let { result: {status, msg} } = await request.post("/work_ai", "/org/platform/account/authorize/check", { key })
            console.log('check:' + msg)
            let config = {
                '-1':async ()=>{//授权超时
                    message.error(msg)
                    clearTimeout( authorizeTimer.value)
                    let {result: {url, key}} = await debounceScanQRCode()
                    browerView.value?.navigateTo(url)
                    checkUserAuthorize(key)

                },
                0:(key)=>{//授权检查
                    checkUserAuthorize(key)
                },
                1:()=>{//授权失败
                    message.error(msg)
                    clearTimeout( authorizeTimer.value)
                    emit('onError', {
                      appKey: props.appKey
                    })
                },
                2:()=>{///授权成功
                    clearTimeout( authorizeTimer.value)
                    console.log('授权成功xxxxxxxxxx');

                    emit('logined', {
                    appKey: props.appKey
                    })
                    clearAppCache()
                }
            }
            config[status] && config[status](key)

        },1000)
    }

    const executeJavaScript = (jsCode) => {
      return new Promise(resolve => {
        browerView.value.executeJavaScript(jsCode, (res) => {
          resolve(res)
        })
      })
    }

    let logintype = ref('user')
    let timerId = null
    let waitLoading = ref(false)

    const drawerFn = (listen_url) => {
      let requestNum = 0
        browerView.value?.beforeRequest(listen_url, async (res) => {
            if(!waitLoading.value){
              // if(app.value.key === 'douyin' && logintype.value === 'org'){
                pageLoading.value = true
              // }
                await utils.delay(6000)
                waitLoading.value = true
            }
            timerId && clearInterval(timerId)
            timerId = null

            if(app.value.key === 'douyin') {
            if(douyinRetryCount.value >= douyinRetryLimit.value){
              clearAppCache()
              douyinRetryCount.value = 0
              message.error('授权失败, 请重新扫码授权')

              emit('onError', {
                appKey: props.appKey
              })
              return
            }

            try {

              await retryValidateDouyinCertKey()

            } catch (error) {
              douyinRetryCount.value += 1
              browerView.value.reload()

              return
            }

            console.log('logintype.value..如果是[logintype.value] 是【org】 就是机构号........',logintype.value)

            if(logintype.value === 'org'){
              try {
                let ticketRes = await retryGetDouyinTicketCryptCookie()

                const cookies = {
                  ...utils.convertStrCookieToDict(res.headers.Cookie),
                  ...ticketRes
                }

                const [ cookiesStr ] = utils.convertCookies(
                  Object.keys(cookies).reduce((cookieObj, cookieKey) => {
                    cookieObj.push({
                      name: cookieKey,
                      value: cookies[cookieKey],
                    })

                    return cookieObj
                  }, [])
                )
                res.headers.Cookie = cookiesStr
                console.log('logintype.value org..cookiesStr........',cookiesStr)
              } catch (error) {
                pageLoading.value = false
                console.log(error, 'zzzzzzzzzzzz')
                message.error('授权失败, 请重新扫码授权')
                return
              }
            }

            douyinRetryCount.value = 0

            waitLoading.value = false

            const localData = [
              'security-sdk/s_sdk_cert_key',
              'security-sdk/s_sdk_crypt_sdk',
              'security-sdk/s_sdk_pri_key',
              'security-sdk/s_sdk_pub_key',
              'security-sdk/s_sdk_server_cert_key',
              'security-sdk/s_sdk_sign_data_key/token',
              'security-sdk/s_sdk_sign_data_key/web_protect',
            ]

            const localDataPromises = localData.map((item) => {
              console.log('localDataPromises-item---',item)
              return executeJavaScript(`localStorage.getItem("${item}");`).then(res => {
                return {
                  key: item,
                  value: res,
                }
              })
            })

            const localDataResult = await Promise.all(localDataPromises)

            res = {
              ...res,
              headers: {
                ...res.headers,
                localdata: localDataResult.filter(item => item.value),
              },
            }

            console.log(res, 'res')
          }


          if(!app.value){
            return
          }

          if(app.value.is_scan_authorize){
            console.log('开始扫码授权');

            if(requestNum==0){
              requestNum++
              let {result: {url, key}} = await debounceScanQRCode()
              browerView.value?.navigateTo(url)
              console.log('url', url);
              checkUserAuthorize(key)
            }
          }else{
            if(requestNum==0){
            requestNum++
            emit('logined', {
              appKey: props.appKey,
              loginType: logintype.value,
              ...res
            })
            clearAppCache()
           }
          }
        })
    }
    const douyinRetryLimit = ref(5)
    const douyinRetryCount = ref(0)
    const douyinRetryValidLimit = ref(6)

    const retryValidateDouyinCertKey = async () => {
      let frequency = 0

      return new Promise(async (resolve, reject) => {
        let timer = setInterval(async () => {
          if(frequency >= douyinRetryValidLimit.value){
            clearInterval(timer)
            reject()
            return
          }

          let res = await executeJavaScript(`localStorage.getItem("security-sdk/s_sdk_cert_key");`)
          let data = JSON.parse(res)

          console.log('douyin:security-sdk/s_sdk_cert_key', data)

          if(isUnDef(data.key)){
            clearInterval(timer)
            resolve()
            return
          }

          frequency += 1
        }, 1000)
      })
    }

    const retryGetDouyinTicketCryptCookie = async () => {
      let frequency = 0

      return new Promise(async (resolve, reject) => {
        let timer = setInterval(async () => {
          if(frequency >= 15){
            clearInterval(timer)
            reject()
            return
          }

          let res = await executeJavaScript(`document.cookie;`)
          let data = utils.convertStrCookieToDict(res)

          if(isDef(data._bd_ticket_crypt_cookie)){
            clearInterval(timer)

            resolve({
              _bd_ticket_crypt_cookie: data._bd_ticket_crypt_cookie,
              _bd_ticket_crypt_doamin: data._bd_ticket_crypt_doamin
            })

            return
          }

          frequency += 1
        }, 1000)
      })
    }

    const debounceScanQRCode = useDebounceFn(scanQRCode, 1000)

    watch(logintype, (val) => {
      if (val == 'user') {
        console.log('触发一次111');

          drawerFn(app.value.listen_url)
      } else {
        console.log('触发一次222222');
          drawerFn(app.value.org_listen_url)
      }
    })

const createAppWindow = async () => {
      console.log(props.proxy, props.userAgent, '创建窗口 拿到参数了嘛??');
      
        browerView.value = await window.client.createBrowerView(
            app.value.login_url,
            {
                width: parseInt(width.value),
                height: parseInt(height.value),
                y: parseInt(y.value),
                x: parseInt(x.value)
          },
          {
            proxy: props.proxy,
            userAgent:props.userAgent
          }
          
        )

        if (app.value.key === 'douyin') {
            timerId = setInterval(() => {
              executeJavaScript(`localStorage.getItem("LOGIN_STATUS");`).then(res => {
                  if (res) {
                    let data = JSON.parse(res)
                    console.log('douyin:LOGIN_STATUS', data)
                    if (!isEmpty(data)) {
                      logintype.value = data.logintype
                    }
                  }
              })
            }, 1000)
        }

        browerView.value?.show()
        console.log('触发一次3333');
        drawerFn(app.value.listen_url)
    }

    onUnmounted(() => {
        destoryAppWindow()
    })

    const destoryAppWindow = () => {
        browerView.value?.destory()

        authorizeTimer.value && clearTimeout(authorizeTimer.value)
        authorizeTimer.value = null

        timerId && clearInterval(timerId)
    }

    const retreatAppPage = () => {
        browerView.value?.retreat()
    }

    const forwardAppPage = () => {
        browerView.value?.forward()
    }

    const reloadAppPage = () => {
        browerView.value?.reload()
    }

    const resizeAppWindow = () => {
        browerView.value?.resize({
            width: parseInt(width.value),
            height: parseInt(height.value),
            y: parseInt(y.value),
            x: parseInt(x.value),
        })
    }

    const clearAppCache = () => {
        browerView.value?.clearCache()
    }

    watch([width, height, x, y], () => {
        if(targetIsVisible.value){
            resizeAppWindow()
        }
    })
</script>

<template>
    <div class="flex relative flex-col w-full h-full manage-warp">
        <div class="flex items-center header">
            <div class="flex items-center">
                <div class="cursor-pointer" @click="retreatAppPage">
                    <ArrowLeftOutlined style="font-size: 16px;"/>
                </div>
                <div class="ml-10 cursor-pointer" @click="forwardAppPage">
                    <ArrowRightOutlined style="font-size: 16px;"/>
                </div>
                <div class="ml-10 cursor-pointer" @click="reloadAppPage">
                    <Loading3QuartersOutlined style="font-size: 16px;"/>
                </div>
            </div>
            <div class="flex flex-1 ml-30">
                <div class="flex cursor-pointer app" v-if="app">
                    <div class="flex-1 text-center text">{{ app.value }} - 请勿手动关闭该页面！请耐心等待程序自动关闭！</div>
                </div>
            </div>
            <div class="flex items-center">
                <div class="cursor-pointer" style="color: #9d70ff;" @click="clearAppCache"> 清除当前页面缓存 </div>
                <div class="ml-10">
                    <slot name="header_after"></slot>
                </div>
            </div>
        </div>
        <div class="container flex justify-center h-full align-center" ref="windowViewRef">
            <div><img src="../../../common/image/loading.gif" style="transform:scale(.3)"/></div>
        </div>
    </div>
</template>

<style lang="less" scoped>

    .header {
        height: 35px;
        line-height: 35px;
        padding: 0 10px;

        .app {
            padding: 0px 10px;
            border: 1px solid #ccc;
            border-top: none;
            background:rgb(255, 0, 68);

            .text {
                color: #fff !important;
            }
        }
    }

    .container {
        height: calc(100% - 35px);
        width: 100%;
    }
</style>

<style lang="less">
    .manage-warp .app svg {
        color: #fff;
    }
    .page-loading{
      position: absolute;
      inset: 0 ;
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: rgba(000, 000, 000,.3);
      z-index: 99999;
    }
</style>
